package memory.memoryCopy;

/**
 * @Author wsyjiamian@163.com
 * @Description 实现深拷贝
 * @Date 2020/8/16 12:58
 */

public class RealizeFullCopy {

    public static void main(String[] args) {
        RealizeFullCopy rc = new RealizeFullCopy();
        rc.fullCopyTypeOne();
        rc.fullCopyTypeTwo();
    }

    //实现深拷贝方式一
    //所有对象都实现Cloneable接口，重写Object中的clone方法
    public void fullCopyTypeOne(){
        try {
            User u = new User("zs" , 10 , new IDCard("123" , "成都"));
            User u1 = (User) u.clone();
            u.idCard.address = "上海"; //对原数据进行修改
            System.out.println("执行深拷贝后，对原数据进行修改后，拷贝后的数据："+u1.idCard.address); //不影响深拷贝后的数据
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

    //实现深拷贝方式二
    //仿照C++，实现拷贝构造函数
    public void fullCopyTypeTwo(){
        User u = new User("zs" , 10 , new IDCard("123" , "成都"));
        User u2 = new User(u);
        u.idCard.idCard = "456";
        System.out.println("执行深拷贝后，对原数据进行修改后，拷贝后的数据："+u2.idCard.idCard); //不影响深拷贝后的数据
    }

    static class User implements Cloneable{
        String name;
        int age;
        IDCard idCard;

        //拷贝构造函数
        public User(User u){
            this.name = u.name;
            this.age = u.age;
            idCard = new IDCard();
            this.idCard.idCard = u.idCard.idCard;
            this.idCard.address = u.idCard.address;
        }

        public User(String name , int age , IDCard idCard){
            this.name = name;
            this.age = age;
            this.idCard = idCard;
        }


        @Override
        public Object clone() throws CloneNotSupportedException {
            User user =  (User)super.clone();
            user.name = this.name;
            user.age = this.age;
            IDCard ic = (IDCard)idCard.clone();
            user.idCard = ic;
            return user;
        }


       /* @Override
       public String toString() {
            return "[name: "+name+", age: "+age+", idCard: "+idCard.toString()+"]";
        }*/
    }

    static class IDCard implements Cloneable{
        String idCard;
        String address;

        public IDCard(){

        }

        public IDCard(String idCard , String address){
            this.idCard = idCard;
            this.address = address;
        }

        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

        /*
        @Override
        public String toString() {
            return "[idCard: "+idCard+" , address: "+address+"]";
        }
        */
    }
}
